﻿using BCCommon;
using BCCommon.PaymentEnums;
using BCCommon.TMS.Order;
using BCCommon.TMS.Transport;
using BCDto.TMS.Order;
using BCDto.TMS.Order.Order;
using BCDto.TMS.Order.OrderEvaluation;
using BCDto.TMS.OrderExtentionGoodsChecklist;
using BCDto.TMS.OrderFreightRecord;
using BCDto.TMS.OrderPackingRecord;
using BCDto.TMS.OrderSpecificServiceRecord;
using BCDto.TMS.OrderTranstionRecord;
using BCService.TMS.Order.Order;
using BCService.TMS.Order.OrderEvaluation;
using BCService.TMS.Order.OrderGoodsChecklist;
using BCService.TMS.OrderExtentionGoodsChecklist;
using BCService.TMS.OrderFreightRecord;
using BCService.TMS.OrderPackingRecord;
using BCService.TMS.OrderSpecificServiceRecord;
using BCService.TMS.OrderTranstionRecord;
using BCService.TMS.TransportOrder;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace BCTMSRESTful.Controllers.ClientApp.Order
{
    /// <summary>
    /// 订单
    /// </summary>
    [ApiExplorerSettings(GroupName = "ClientApp")]
    [Route("api/v1/ClientApp/[controller]")]
    public class OrderController : ClientAppBaseController
    {
        private readonly ITransportOrderService transportOrderService;
        private readonly IOrderProcessService orderProcessService;
        private readonly IOrderExtentionGoodsChecklistService orderExtentionGoodsChecklistService;
        private readonly IOrderFreightRecordService orderFreightRecordService;
        private readonly IOrderSpecificServiceRecordService orderSpecificServiceRecordService;
        private readonly IOrderPackingRecordService orderPackingRecordService;
        private readonly IOrderEvaluationService orderEvaluationService;
        private readonly IOrderTranstionRecordService orderTranstionRecordService;
        public OrderController(ITransportOrderService transportOrderService,
            IOrderProcessService orderProcessService,
            IOrderExtentionGoodsChecklistService orderExtentionGoodsChecklistService,
            IOrderFreightRecordService orderFreightRecordService,
            IOrderSpecificServiceRecordService orderSpecificServiceRecordService,
            IOrderPackingRecordService orderPackingRecordService,
             IOrderEvaluationService orderEvaluationService,
             IOrderTranstionRecordService orderTranstionRecordService)
        {
            this.transportOrderService = transportOrderService;
            this.orderProcessService = orderProcessService;
            this.orderExtentionGoodsChecklistService = orderExtentionGoodsChecklistService;
            this.orderFreightRecordService = orderFreightRecordService;
            this.orderSpecificServiceRecordService = orderSpecificServiceRecordService;
            this.orderPackingRecordService = orderPackingRecordService;
            this.orderEvaluationService = orderEvaluationService;
            this.orderTranstionRecordService = orderTranstionRecordService;
        }

        #region 下单前计算运费
        /// <summary>
        /// 下单前计算运费
        /// </summary>
        /// <response code="200">运费计算结果</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(IEnumerable<OrderCostChecklistDto>), 200)]
        [AllowAnonymous]
        public IActionResult CalculateFreight([FromBody] OrderShippingCostRequestDto orderShippingCostRequestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(orderShippingCostRequestDto.TransportBusinessType, orderShippingCostRequestDto.SuiteBusinessType);
            var result = orderService.CalculateShippingCost(this.UserInfo?.UserId, orderShippingCostRequestDto);
            return Ok(result);
        }

        #endregion 下单前计算运费

        #region 创建无忧搬家订单
        /// <summary>
        /// 创建无忧搬家订单
        /// </summary>
        /// <param name="requestDto">无忧搬家订单信息</param>
        /// <response code="201">订单创建成功</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(OrderDto), 201)]
        public IActionResult WorryFreeMoving([FromBody] WorryFreeMoveSuiteOrderRequestDto requestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(TransportBusinessType.Moving, VehicleSuiteBusinessType.WorryFreeMove);
            var result = orderService.Create(requestDto, this.UserInfo.UserId,null);
            return Created(string.Format("api/v1/ClientApp/Orders/{0}", result.OrderId), result);
        }

        #endregion

        #region 创建便捷搬家订单
        /// <summary>
        /// 创建无忧搬家订单
        /// </summary>
        /// <param name="requestDto">便捷搬家订单信息</param>
        /// <response code="201">订单创建成功</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(OrderDto), 201)]
        public IActionResult EasyMoving([FromBody] EasyMoveSuiteOrderRequestDto requestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(TransportBusinessType.Moving, VehicleSuiteBusinessType.EasyMove);
            var result = orderService.Create(requestDto, this.UserInfo.UserId, null);
            return Created(string.Format("api/v1/ClientApp/Orders/{0}", result.OrderId), result);
        }
        #endregion

        #region 创建跑腿订单
        /// <summary>
        /// 创建跑腿订单
        /// </summary>
        /// <param name="requestDto">跑腿订单信息</param>
        /// <response code="201">订单创建成功</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(OrderDto), 201)]
        public IActionResult RunErrands([FromBody] RunErrandsOrderRequestDto requestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(TransportBusinessType.RunErrands, null);
            var result = orderService.Create(requestDto, this.UserInfo.UserId, null);
            return Created(string.Format("api/v1/ClientApp/Orders/{0}", result.OrderId), result);
        }
        #endregion

        #region 创建同城订单
        /// <summary>
        /// 创建同城订单
        /// </summary>
        /// <param name="requestDto">同城订单信息</param>
        /// <response code="201">订单创建成功</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(OrderDto), 201)]
        public IActionResult SameCity([FromBody] SameCityOrderRequestDto requestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(TransportBusinessType.SameCity, null);
            var result = orderService.Create(requestDto, this.UserInfo.UserId, null);
            return Created(string.Format("api/v1/ClientApp/Orders/{0}", result.OrderId), result);
        }
        #endregion

        #region 创建小件订单
        /// <summary>
        /// 创建小件订单
        /// </summary>
        /// <param name="requestDto">小件订单信息</param>
        /// <response code="201">订单创建成功</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [ProducesResponseType(typeof(OrderDto), 201)]
        public IActionResult SmallPieces([FromBody] SmallPiecesOrderRequestDto requestDto)
        {
            IOrderService orderService = transportOrderService.GetOrderService(TransportBusinessType.SmallPieces, null);
            var result = orderService.Create(requestDto, this.UserInfo.UserId, null);
            return Created(string.Format("api/v1/ClientApp/Orders/{0}", result.OrderId), result);
        }
        #endregion

        #region 获取订单信息
        /// <summary>
        /// 获取订单信息
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <response code="200">获取订单信息</response>
        /// <returns></returns>
        [HttpGet("{order_id}")]
        [ProducesResponseType(typeof(OrderDto), 200)]
        public IActionResult GetOrderInfo([FromRoute(Name = "order_id")] long orderId)
        {
            return Ok(this.orderProcessService.GetWithUser(this.UserInfo.UserId, orderId));
        }
        #endregion

        #region 取消订单
        /// <summary>
        /// 取消订单
        /// </summary>
        /// <param name="orderCancelRequestDto">取消订单信息</param>
        /// <response code="200">订单列表</response>
        /// <returns></returns>
        [HttpPut("[action]")]
        public IActionResult CancelOrder([FromBody] OrderCancelRequestDto orderCancelRequestDto)
        {
            this.orderProcessService.CancelOrder(this.UserInfo, null, SourceAppType.ClientApp, orderCancelRequestDto);
            return Ok();
        }
        #endregion

        #region 获取已接单列表

        /// <summary>
        /// 获取待抢订单列表
        /// </summary>
        /// <param name="userAppOrderStatus">订单状态</param> 
        /// <param name="index">页码。</param>
        /// <param name="size">页数</param>
        /// <returns></returns>
        /// <response code="200">获取已接单订单列表。</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="401">请求需要认证或者认证信息已过期。</response>
        /// <response code="403">无权访问指定的功能。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        [HttpGet("[action]")]
        [ProducesResponseType(typeof(PageableList<OrderDto>), 200)]
        public IActionResult Query(UserAppOrderStatus userAppOrderStatus, [FromQuery(Name = "index")] int index = 1, [FromQuery(Name = "size")] int size = 10)
        {
            return this.Ok(this.orderProcessService.ClientAppQueryOrders(userAppOrderStatus, this.UserInfo.UserId, index, size));
        }
        #endregion

        #region 获取货物清单
        /// <summary>
        /// 获取货物清单
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        /// <response code="200">获取已接单订单列表。</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="401">请求需要认证或者认证信息已过期。</response>
        /// <response code="403">无权访问指定的功能。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        [HttpGet("[action]/{order_id}")]
        [ProducesResponseType(typeof(IEnumerable<OrderExtentionGoodsChecklistDto>), 200)]
        public IActionResult GoodsChecklist([FromRoute(Name = "order_id")] long orderId)
        {
            return this.Ok(this.orderExtentionGoodsChecklistService.GetList(orderId));
        }
        #endregion

        #region 获取订单费用清单
        /// <summary>
        /// 获取订单费用清单
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        /// <response code="200">获取订单费用清单。</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="401">请求需要认证或者认证信息已过期。</response>
        /// <response code="403">无权访问指定的功能。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        [HttpGet("[action]/{order_id}")]
        [ProducesResponseType(typeof(IEnumerable<OrderFreightRecordDto>), 200)]
        public IActionResult FreightRecord([FromRoute(Name = "order_id")] long orderId)
        {
            return this.Ok(this.orderFreightRecordService.GetList(orderId));
        }
        #endregion

        #region 获取订单特殊服务
        /// <summary>
        /// 获取订单特殊服务
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        /// <response code="200">获取订单特殊服务。</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="401">请求需要认证或者认证信息已过期。</response>
        /// <response code="403">无权访问指定的功能。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        [HttpGet("[action]/{order_id}")]
        [ProducesResponseType(typeof(IEnumerable<OrderSpecificServiceRecordDto>), 200)]
        public IActionResult SpecificService([FromRoute(Name = "order_id")] long orderId)
        {
            return this.Ok(this.orderSpecificServiceRecordService.GetList(orderId));
        }
        #endregion

        #region 获取订单包装材料
        /// <summary>
        /// 获取订单包装材料
        /// </summary>
        /// <param name="orderId">订单Id</param>
        /// <returns></returns>
        /// <response code="200">获取订单包装材料。</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="401">请求需要认证或者认证信息已过期。</response>
        /// <response code="403">无权访问指定的功能。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        [HttpGet("[action]/{order_id}")]
        [ProducesResponseType(typeof(IEnumerable<OrderPackingRecordDto>), 200)]
        public IActionResult Packing([FromRoute(Name = "order_id")] long orderId)
        {
            return this.Ok(this.orderPackingRecordService.GetList(orderId));
        }
        #endregion

        #region 用户评价
        /// <summary>
        /// 用户评价
        /// </summary>
        /// <param name="orderUserEvaluationRequestDto">用户订单评价</param>
        /// <response code="200">用户评价</response>
        /// <returns></returns>
        [HttpPut("[action]")]
        [ProducesResponseType(typeof(OrderEvaluationDto), 200)]
        public IActionResult Evaluate([FromBody] OrderUserEvaluationRequestDto orderUserEvaluationRequestDto)
        {
            OrderEvaluationDto orderEvaluationDto = new OrderEvaluationDto()
            {
                UserId = this.UserInfo.UserId,
                OrderId = orderUserEvaluationRequestDto.OrderId,
                UserEvaluation = orderUserEvaluationRequestDto.UserEvaluation,
                UserEvaluationContent = orderUserEvaluationRequestDto.UserEvaluationContent
            };
            return Ok(this.orderEvaluationService.UserEvaluate(orderEvaluationDto));
        }
        #endregion

        #region 订单流转记录
        #region 获取订单流转记录
        /// <summary>
        ///  获取订单流转记录
        /// </summary>
        /// <param name="orderTranstionRecordId">订单流转记录Id</param>
        /// <response code="200">获取订单流转记录</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        /// <returns></returns>
        [HttpGet("[action]/{order_transtion_record_id}")]
        [ProducesResponseType(typeof(OrderTranstionRecordDto), 200)]
        public IActionResult TranstionRecord([FromRoute(Name = "order_transtion_record_id")] long orderTranstionRecordId)
        {
            return StatusCode((int)HttpStatusCode.OK, this.orderTranstionRecordService.Get(orderTranstionRecordId));
        }
        #endregion

        #region 获取订单流转记录列表
        /// <summary>
        ///  获取订单流转记录列表
        /// </summary>
        /// <response code="200">获取订单流转记录列表</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        /// <returns></returns>
        [HttpGet("[action]/{order_id}")]
        [ProducesResponseType(typeof(IEnumerable<OrderTranstionRecordDto>), 200)]
        public IActionResult TranstionRecordTimeline([FromRoute(Name = "order_id")]long orderId)
        {
            return StatusCode((int)HttpStatusCode.OK, this.orderTranstionRecordService.GetList(orderId));
        }
        #endregion
        #endregion

    }
}
